This document summarizes some of the major changes from Developer Release 3 (August ’95) to Developer Release 4 (November ’95) that will require you to change your source code. This is not an exhaustive list, but points out the major changes that will affect most part editors. Nor does it attempt to go into full detail; in most cases, the relevant recipe documents will give you the information you need to implement the changes. The sample parts also show how things should be done.
Most of the changes that occurred between DR3 (beta) and DR4 (final) were under the hood — bug fixes and optimizations — and won't affect your parts. Documents will just run faster, in less memory, more reliably.
Binary compatibility was not preserved between DR3 and DR4. All old editors must be removed and will crash if you try to use them. (Empty the Editors folders on all mounted disks!) However, DR4 is the final 1.0 release and we will make every effort to preserve binary compatibility in the future.
If your part editor was derived from sample code like SamplePart, ODLeafPart (“HelloPart”) or the Peng-based parts, it might be easiest to take the DR4 version of the sample part and copy your editor-specific changes into it, rather than trying to rev your entire existing code. In fact, if you were using an unsupported source base, particularly ODLeafPart, you might consider switching to using the sample parts (e.g. SamplePart) as your source base: they are now very complete, have been extensively reviewed and debugged, and support the recipes properly.
A New Version Of SOM
OpenDoc now uses SOMobjects™ for Mac™ OS, an optimized implementation of the System Object Model™ (SOM). The data structures allocated by SOM itself have been reduced down to about 10% of their size in DR3, and SOM now loads and initializes classes much more quickly, which improves launch times.
• Don't forget to update the SOM files (headers, libraries, scripts, tools) in your MPW or ToolServer folder. Even if you don't use MPW to build your part, you do need it to compile your .idl file, so you need the new SOM compiler. The files are in “Development: CFM68K and SOM: MPW Additions:”.
• Remove the library “SOM” from your project/makefile and replace it with “SOMLib”, which is in the SOM folder of your environment additions folder.
• Since the new SOM's data structures are significantly different, you'll need to toss out any existing SOM-generated header files (.xh and .xih) for your editor, and run the new SOM compiler to regenerate them from the IDL file. (The sample parts on this CD of course come with up-to-date headers.)
• You'll also need to change your editor library's exports. Previously, editors did not need to export any symbols. Now, however, they need to export the “ClassData” symbol declared by SOM in your part's .xih file. For instance, if your SOM classname is MyEditor, you need to export MyEditorClassData.
• Libraries no longer have a special SOMInit routine. Previously, this routine was named as the “main” function of the library, and SOM called it when it loaded the library. This no longer happens. You can remove this function.
• Some core functions and methods that are part of the SOM API itself have been renamed or changed. Most editors won't need to use these. If you were using any special SOM functions such as somFindClass, consult the SOM documentation on this CD to see what's changed.
API Changes
We tried not to change the OpenDoc APIs, but we discovered a few problems that could not be worked around in any other way.
• Methods that returned structures of type ODPoint, ODRect or ODPolygon as the function result have been modified to return the structure in an “out” parameter instead (you pass a pointer to the structure and the method fills it in with the result.) Not only does this generate more efficient code, but it also prevents a serious conflict with some C++ compilers when the caller is not using the AltPoint or AltPoly utilities. The methods affected are:
ODTransform::TransformPoint
ODTransform::InvertPoint
ODShape::CopyPolygon
ODFrame::GetContentExtent
When calling these methods, instead of assigning the result to a variable, you now pass the address of the variable as the final parameter.
• ODWindowState::RegisterWindow now takes an additional boolean parameter called shouldDispose. This sets the shouldDispose property of the new ODWindow object. This property was formerly set via the window's SetShouldDispose method, which has been removed.
If you were formerly calling SetShouldDispose(ev,kODFalse) on the window after registering it (because you allocated your own storage for the WindowRecord) you should remove that call and pass kODFalse as the value of the shouldDispose parameter to RegisterWindow. If you were not calling SetShouldDispose (because you allocated the WindowRecord in the application heap using NewPtr) you should pass kODTrue as the value of shouldDispose.
• ODObject no longer defines an IsInitialized method. In your own objects' Initialize methods, just call the parent method. There is no need to check if the parent has been initialized already.
• ODLinkManager::CreateLink, ODLink::GetLinkSource, ODLinkSource::GetLink and ODLinkSource::ShowSourceContent were never meant to be public but were declared so accidentally. They've now been made private and can't be called by parts (you shouldn't ever need to call them anyway.)
• ODDraft::CreateFrame now takes a parameter of type ODObjectType (a char*) for the frame type.
• ODMessageInterface::Send now takes both a toFrame and fromPart reference, either of which can be null. This affects recordable parts and any other parts which use the message interface to send semantic events.
• ODSession::GetUserName no longer returns a pointer to an ODIText: returning pointers is incompatible with CORBA and DSOM. It now returns that data in an “out” parameter.
• The type DragReference declared in DragDrp.idl has been renamed ODPlatformDragReference.
Error Codes
• OpenDoc's error number range has changed; we used to use positive numbers, now we use negative ones in the range -29600 ... -29849. If you were using the error constants you shouldn't need to change anything. If you weren't, please do so!
• Parts that declare their own error codes, especially ones that might be returned to external callers, should number them starting at 200.
• A new error code kODErrAlreadyNotified can be returned by parts if they want to return an error status but have already notified the user by putting up a dialog. This error will still signal that the operation failed, but will not cause the shell to put up another error dialog. If you use the Except utility, you can use SetErrorCode in your CATCH or SOM_CATCH block to change the error number.
• Some error codes used only by utilities (e.g. kODErrAssertionFailed) have been moved from ErrorDef.idl to UtilErrs.h.
Utilities
• There is a new utility called TempIter. It contains a set of TempObj classes (“smart pointers” to SOM objects that ensure the objects are deleted when the pointers go out of scope) that simplify working with OpenDoc iterator objects.
• The FocusLib utility now allows the caller to focus to frame coordinates as well as to content coordinates. This is very useful for drawing things like scrollbars that do not scroll with your content.
• The functions ODGetIconFamilyProp and ODSetIconFamilyProp now take extra parameters. See the header <StdTypIO.h> for details.
Other Changes
• OpenDoc DR4 now uses the official ISO-string prefix registered to CILabs. ISO strings in OpenDoc used to begin with “OpenDoc:...” or “Apple:...” but now include a long and cryptic-looking prefix. As long as you use the named constants for the standard ISO strings you'll be fine, but any you define (for instance, special data types, property names, categories, etc.) will need to be revised to include the ISO prefix, otherwise OpenDoc will not be able to load your editor. If in doubt, take a look at the sample code’s source files.
• Frames now have an in-limbo property visible to parts via the new methods IsInLimbo and SetInLimbo. Parts must inspect and/or set this property during data interchange. The recipe documents for data interchange discuss manipulation of this flag during data interchange. For a complete description, including information on how to use the in-limbo flag during Undo operations, see the OpenDoc Programmer's Guide.
• Some changes to the implementation of OpenDoc affect parts supporting linking. The Linking recipe documents summarize these changes and discuss each in detail.
• ODShape::ReadShape would formerly delete the receiver (the shape object) and return NULL if the storage unit property did not contain a shape. This weird bit of behavior has been removed. If the property does not contain a shape, the shape will simply be set to empty.
• The UserString namespaces are now ValueNameSpaces, not ObjectNameSpaces. These were probably not being used by many parts, but if you were using them, see the utility BndNSUtl for examples of how to access them.
• Parts must now call ODClipboard methods ActionDone, ActionUndone and ActionRedone when performing or undo/redo-ing Cut, Copy or Paste commands. See the Clipboard recipe.
• The ODBoolean return values from parts' DragEnter and DragWithin methods are now being used by OpenDoc (they were previously ignored.) If you were accidentally returning false, you will now find that OpenDoc will refuse the drag.
• There is a new Undo method to allow canceling a half-completed transaction.
• Some error codes have been removed, mostly overly-generic ones like kODErrInvalidParameter. They have been replaced by new, more specific codes.
• Shell plug-ins have changed significantly. For instance, they are no longer ODParts! Please refer to the recipe for details.
• If the root part of a document has a type that's a Mac-style OSType (e.g. 'PICT'), the file type of the document will be that OSType with the first byte replaced by a '#' (e.g. '#ICT'.) This has to be done since the file itself is not a valid PICT file (it's probably a Bento file.) Bundle/icon resources for several of these munged types have been added to OpenDoc itself so that editor libraries don't need to define them themselves.